package com.jasonzqshen.ifm.featureModelCore;

import java.util.Collection;
import java.util.LinkedList;

import org.w3c.dom.Element;

import com.jasonzqshen.ifm.collections.treeCollection.*;
import com.jasonzqshen.ifm.collections.treeCollection.factories.*;
import com.jasonzqshen.ifm.featureModelCore.arguments.FeatureNameChangedArgs;
import com.jasonzqshen.ifm.featureModelCore.featureModelInterface.*;
import com.jasonzqshen.ifm.featureModelCore.shapes.*;
import com.jasonzqshen.ifm.utils.Identifier;

public class FeatureTreeRoot extends TreeRoot implements Feature {

    public static final TreeRootFactory FACTORY = new TreeRootFactory(
            FeatureTreeRoot.class.getName()) {

        @Override
        public FeatureTreeRoot constructNewInstance(Identifier id, Object[] args) {
            if (args == null || args.length != 1
                    || !(args[0] instanceof String)) {
                return new FeatureTreeRoot(id);
            }

            String featureName = (String) args[0];
            FeatureTreeRoot root = new FeatureTreeRoot(id);
            root.featureName = featureName;
            return root;
        }

        @Override
        /**
         * XML parser
         * 
         * @param xelem
         * @param obj
         * @throws TreeCollectionException
         */
        public void xmlParser(Element elem, TreeObject treeObject) {
            if (!(treeObject instanceof FeatureTreeRoot)) {
                return;
            }
            FeatureTreeRoot newRoot = (FeatureTreeRoot) treeObject;

            newRoot.featureName = elem.getAttribute(XML_NODE_NAME);
            newRoot.annotation = elem.getAttribute(XML_ANNOTATION);

            newRoot.rectangle = FMRectangle.parseXElem(elem);
        }

    };

    private static final String XML_NODE_NAME = "NodeName";

    private static final String XML_ANNOTATION = "Annotation";

    private String featureName;

    private String annotation;

    private FMRectangle rectangle;

    /**
     * Construct Feature Tree Root
     * 
     * @param id
     */
    public FeatureTreeRoot(Identifier id) {
        super(id);
        featureName = FeatureModel.STRING_EMPTY;
        annotation = FeatureModel.STRING_EMPTY;

        rectangle = new FMRectangle();
    }

    /**
     * Get feature name
     */
    @Override
    public String getFeatureName() {
        return this.featureName;
    }

    /**
     * Set feature name
     */
    @Override
    public void setFeatureName(String featureName) {
        FeatureNameChangedArgs args = new FeatureNameChangedArgs(this,
                featureName);
        this.treeOwner.beforeProcess(this, args);
        this.featureName = featureName;
        this.treeOwner.afterProcess(this, args);
    }

    /**
     * Get annotation
     */
    @Override
    public String getAnnotation() {
        return this.annotation;
    }

    /**
     * set annotation
     */
    @Override
    public void setAnnotation(String annotation) {
        this.annotation = annotation;
    }

    /**
     * get properties
     */
    @Override
    public Collection<FeatureNodeProperty> getProperties() {
        LinkedList<FeatureNodeProperty> properties = new LinkedList<FeatureNodeProperty>();
        for (NonRoot child : this.children.values()) {
            if (child instanceof FeatureNodeProperty) {
                properties.add((FeatureNodeProperty) child);
            }
        }
        return properties;
    }

    /**
     * get children nodes
     */
    @Override
    public Collection<FeatureTreeNode> getChildrenNodes() {
        LinkedList<FeatureTreeNode> nodes = new LinkedList<FeatureTreeNode>();
        for (FeatureTreeGroupRelationship gRelationship : this
                .getChildrenGroupRelationship()) {
            nodes.addAll(gRelationship.getChildrenNodes());
        }
        return nodes;
    }

    /**
     * get children group relationship
     */
    @Override
    public Collection<FeatureTreeGroupRelationship> getChildrenGroupRelationship() {
        LinkedList<FeatureTreeGroupRelationship> gRelationshipes = new LinkedList<FeatureTreeGroupRelationship>();
        for (NonRoot child : this.children.values()) {
            if (child instanceof FeatureTreeGroupRelationship) {
                gRelationshipes.add((FeatureTreeGroupRelationship) child);
            }
        }
        return gRelationshipes;
    }

    /**
     * get rectangle
     */
    @Override
    public FMRectangle getShape() {
        return this.rectangle;
    }

    /**
     * set rectangle
     */
    @Override
    public void setShape(FMRectangle shape) {
        this.rectangle = shape;
    }

}
